﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using AMM.Model;
using AMM.Model.Store;

namespace AMM.DataAccess.Store {
    public class MaterialInventoryRepository : BaseRepository<MaterialInventory> {

        private int _pageSize;

        public MaterialInventoryRepository(int pageSize) {
            this._pageSize = pageSize;
        }

        public MaterialInventory FetchMaterialInventoryById(int materialInventoryId) {
            using (var ctx = this.Context) {
                return ctx.MaterialInventories
                    .FirstOrDefault(x => x.MaterialInventoryId == materialInventoryId);
            }
        }

        public void InsertMaterialInventory(MaterialInventory materialInventory) {
            using (var ctx = this.Context) {
                using (DbContextTransaction trans = ctx.Database.BeginTransaction()) {
                    try {
                        MaterialStore ms = ctx.MaterialStores.FirstOrDefault(x =>
                              x.StoreBasisId == materialInventory.StoreBasisId &&
                              x.MaterialId == materialInventory.MaterialId);

                        ms.Quantity = materialInventory.Quantity;
                        ctx.MaterialStores.Attach(ms);
                        ctx.Entry(ms).State = EntityState.Modified;

                        ctx.MaterialInventories.Add(materialInventory);
                        ctx.Entry(materialInventory).State = EntityState.Added;

                        ctx.SaveChanges();
                        trans.Commit();
                    }
                    catch (Exception ex) {
                        trans.Rollback();
                        throw ex;
                    }
                }
            }
        }

        public void DeleteMultipleMaterialInventory(params int[] materialInventoryIds) {
            using (var ctx = this.Context) {
                using (DbContextTransaction trans = ctx.Database.BeginTransaction()) {
                    try {
                        ctx.MaterialInventories.Where(x => materialInventoryIds.Contains(x.MaterialInventoryId)).ToList().ForEach(x => {
                            ctx.MaterialInventories.Remove(x);
                        });
                        ctx.SaveChanges();
                        trans.Commit();
                    }
                    catch (Exception ex) {
                        trans.Rollback();
                        throw ex;
                    }
                }
            }
        }

        public List<MaterialInventory> FetchMaterialInventoryList(MaterialInventorySearchModel searchModel, int pageIndex) {
            using (var ctx = this.Context) {
                var query = ctx.MaterialInventories
                    .Include("Material")
                    .Include("StoreBasi")
                    .Where(x => x.MaterialInventoryId != 0);

                if (!string.IsNullOrEmpty(searchModel.MaterialCode)) {
                    query = query.Where(x => x.Material.Code.Contains(searchModel.MaterialCode));
                }
                if (!string.IsNullOrEmpty(searchModel.StoreBasisCode)) {
                    query = query.Where(x => x.StoreBasi.Code.Contains(searchModel.StoreBasisCode));
                }
                if (searchModel.MaterialInStoreDateStart.HasValue) {
                    query = query.Where(x => x.CreatedDatetime >= DbFunctions.TruncateTime(searchModel.MaterialInStoreDateStart.Value));
                }
                if (searchModel.MaterialInStoreDateEnd.HasValue) {
                    query = query.Where(x => x.CreatedDatetime <= DbFunctions.TruncateTime(searchModel.MaterialInStoreDateEnd.Value));
                }

                searchModel.Records = query.Count();
                pageIndex = (pageIndex - 1) * this._pageSize > searchModel.Records ? 1 : pageIndex;

                return query.OrderByDescending(x => x.CreatedDatetime).Skip((pageIndex - 1) * this._pageSize).Take(this._pageSize).ToList();
            }
        }
    }
}
